package org.jiucai.cas.auth.web;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.jiucai.appframework.base.spring.web.BaseController;
import org.jiucai.appframework.common.encode.MD5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import org.jiucai.cas.auth.service.AuthCheckService;
import org.jiucai.cas.auth.service.AuthResultService;
import org.jiucai.cas.auth.service.AuthService;
import org.jiucai.cas.data.Constant;
import org.jiucai.cas.domain.AuthQuery;
import org.jiucai.cas.domain.UserInfo;

/**
 * 用户登录注销控制器
 * 
 * 所有的异常将统一有配置的bean exceptionResolver 进行处理
 * 
 * @author zhaidw
 */
@Controller
@RequestMapping("/auth")
public class AuthController extends BaseController {

	@Autowired
	protected AuthService authService;
	
	@Autowired
	protected AuthResultService authResultService;
	
	@Autowired
	protected AuthCheckService authCheckService;

	
	public AuthService getAuthService() {
		return authService;
	}

	public void setAuthService(AuthService authService) {
		this.authService = authService;
	}

	public AuthResultService getAuthResultService() {
		return authResultService;
	}

	public void setAuthResultService(AuthResultService authResultService) {
		this.authResultService = authResultService;
	}
	
	/**
	 * 用户登录
	 * 
	 * @param model
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "sso")
	public void userSSO(Map<String, Object> model, HttpServletRequest request,
			HttpServletResponse response) {

		log.debug("userSSO ...");

		try {

			boolean isFailed = false;

			String u = request.getParameter(Constant.REQ_AUTH_UID);
			String t = request.getParameter(Constant.REQ_AUTH_TS);
			String k = request.getParameter(Constant.REQ_AUTH_KEY);
			String r = request.getParameter(Constant.REQ_AUTH_URL);

			if (StringUtils.isEmpty(u) || StringUtils.isEmpty(t)
					|| StringUtils.isEmpty(k)) {
				isFailed = true;
			}
			if (StringUtils.isBlank(u) || StringUtils.isBlank(t)
					|| StringUtils.isBlank(k)) {
				isFailed = true;
			}

			if (isFailed) {
				request.setAttribute("failed_msg", "参数错误。");
				request.setAttribute("return_url", r);

				authResultService.onLoginFailed(request, response);

			}

			if (!isFailed) {
				String authMsg = "";
				Long uid = Long.parseLong(u);
				Long ts = Long.parseLong(t);

				// 检查权限
				authMsg = authService.checkKey(uid, ts, k);

				if (null == authMsg) {

					AuthQuery query = new AuthQuery();
					query.setUserId(uid);
					Boolean hasModule = authService.checkUser(query);
					if (!hasModule) {
						request.setAttribute("failed_msg", "您没有使用当前系统的权限。");
						request.setAttribute("return_url", r);

						//LogService.log(OpType.login, "用户" + uid + " 通过EmarBox登录失败", request);

						authResultService.onLoginFailed(request, response);
						
						return;
					}

					

					UserInfo user = authService.getUserInfo(query);
					
					if (null == user || null == user.getUserId()) {
						request.setAttribute("failed_msg", "用户不存在。");
						authResultService.onLoginFailed(request, response);
					}else{
						//LogService.log(OpType.login, "通过EmarBox登录成功", request);
						authResultService.onLoginSuccess(user, request, response);
					}
		
					return;

				} else {

					request.setAttribute("failed_msg", authMsg);
					request.setAttribute("return_url", r);
					
					authResultService.onLoginFailed(request, response);
					
					return;
				}

			}

		} catch (Exception e) {
			log.error("userSSO failed: ", e);
			try {
				request.setAttribute("failed_msg", "登录失败，请重试。");
				
				authResultService.onLoginFailed(request, response);
				
			} catch (Exception ex) {
				log.error("Request dispatching failed: ", e);
			}
		}
	}

	/**
	 * 用户注销
	 * 
	 * @param model
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "logout")
	public void userLogOut(Map<String, Object> model,
			HttpServletRequest request, HttpServletResponse response) {

		log.debug("userLogOut ...");
		try {

			HttpSession session = request.getSession(true);

			clearSession(session);
			
			authResultService.onLogoutSuccess(request, response);
			
			return;

		} catch (Exception e) {
			
			try {
				authResultService.onLogoutFailed(request, response);
				
			} catch (Exception ex) {
				log.error("Request dispatching failed: ", e);
			}
			
			log.error("userLogOut failed: " +  ExceptionUtils.getFullStackTrace(e));
		}
	}

	/**
	 * 用户登录
	 * 
	 * @param model
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "login")
	public void userLogIn(Map<String, Object> model,
			HttpServletRequest request, HttpServletResponse response) {

		log.debug("userLogIn ...");

		try {

			HttpSession session = request.getSession(true);

			String userName = (String) request.getAttribute(Constant.REQ_PREFIX
					+ "userName");
			String password = (String) request.getAttribute(Constant.REQ_PREFIX
					+ "password");
			String veryCode = (String) request.getAttribute(Constant.REQ_PREFIX
					+ "veryCode");

			String randCode = (String) session.getAttribute("randCode");
			request.setAttribute("userName", userName);

			Integer passwordErrorCountAllowed = 2;

			// 设置密码最大错误次数
			session.setAttribute(Constant.AUTH_SESS_PWD_ERR_MAX_COUNT,
					passwordErrorCountAllowed);

			Integer passwordErrorCount = 0;
			Object sessPwdErrorCount = session
					.getAttribute(Constant.AUTH_SESS_PWD_ERR_COUNT);
			if (null != sessPwdErrorCount) {
				passwordErrorCount = (Integer) sessPwdErrorCount;
				if(null!= passwordErrorCount && passwordErrorCount > 0){
					log.error("密码错误次数: " + passwordErrorCount);
				}
			}

			if (passwordErrorCount > passwordErrorCountAllowed) {
				if (StringUtils.isBlank(veryCode)) {
					request.setAttribute("failed_msg", "验证码不能为空");
					authResultService.onLoginFailed(request, response);
					return;
				}

				if (!veryCode.equals(randCode)) {
					request.setAttribute("failed_msg", "验证码错误");
					authResultService.onLoginFailed(request, response);
					return;
				}
			}

			if (StringUtils.isBlank(userName)) {
				request.setAttribute("failed_msg", "用户名不能为空");
				authResultService.onLoginFailed(request, response);
				return;
			}

			if (StringUtils.isBlank(password)) {
				request.setAttribute("failed_msg", "密码不能为空");
				authResultService.onLoginFailed(request, response);
				return;
			}

			UserInfo login = new UserInfo();
			login.setLoginName(userName);

			UserInfo user = authService.getUserInfo(login);

			//request.setAttribute(LogService.REQ_ATTR_USER_USERNAME, userName);

			if (null == user || null == user.getUserId()) {
				request.setAttribute("failed_msg", "用户不存在");

				//LogService.log(OpType.login, "登录失败，用户 " + userName + " 不存在", request);

				authResultService.onLoginFailed(request, response);
				
				return;
			} else {
				//密码不区分大小写
				if (MD5.encode(password).equalsIgnoreCase(user.getPassword())) {
					
					// 设置会话参数
					session.setAttribute(Constant.AUTH_SESS_PWD_ERR_COUNT, 0);

					//LogService.log(OpType.login, "登录成功", request);
					
					authResultService.onLoginSuccess(user, request, response);

					return;
					
				} else {
					request.setAttribute("failed_msg", "密码不匹配");

					passwordErrorCount++;
					session.setAttribute(Constant.AUTH_SESS_PWD_ERR_COUNT,passwordErrorCount);

					//LogService.log(OpType.login, "使用用户名 " + userName + " 登录失败，密码不匹配，密码尝试次数 " + passwordErrorCount, request);
					
					authResultService.onLoginFailed(request, response);
					
					return;
				}

			}

		} catch (Exception e) {
			try {
				request.setAttribute("failed_msg", "登录失败，请稍后再试。");
		
				authResultService.onLoginFailed(request, response);
				
			} catch (Exception ex) {
				log.error("Request dispatching failed: ", e);
			}
			
			log.error("userLogIn failed: " + ExceptionUtils.getFullStackTrace(e));
		}

	}

	/**
	 * 清除会话内容
	 * 
	 * @param session
	 */
	private void clearSession(HttpSession session) {

		// 密码最大错误次数
		session.removeAttribute(Constant.AUTH_SESS_PWD_ERR_MAX_COUNT);
		// 密码错误次数
		session.removeAttribute(Constant.AUTH_SESS_PWD_ERR_COUNT);

	}

}
